/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.mohas.docsearch.controller;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;

import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.impl.SparseDoubleMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import cern.colt.matrix.linalg.SingularValueDecomposition;

/**
 *
 * @author Muhammad
 */
public class MatrixOperation {

    private double[][] elemen;
    private DoubleMatrix2D matriks;
    private int k;

    public MatrixOperation() {
    }

    public double[][] getElemen() {
        return elemen;
    }

    public void setElemen(double[][] elemen) {
        this.elemen = elemen;
    }

    public DoubleMatrix2D getMatriks() {
        return matriks;
    }

    public void setMatriks(DoubleMatrix2D matriks) {
        this.matriks = matriks;
    }

    public DoubleMatrix2D inverse(DoubleMatrix2D matriks) {
        Algebra aljabar = new Algebra();
        DoubleMatrix2D inv = aljabar.inverse(matriks);

        return inv;
    }

    public DoubleMatrix2D transpose(DoubleMatrix2D matriks) {
        Algebra aljabar = new Algebra();
        DoubleMatrix2D transpose = aljabar.transpose(matriks);

        return transpose;
    }

    public DoubleMatrix2D getU() throws Exception {
        matriks = getMatriksTermDoc();
        SingularValueDecomposition svd = new SingularValueDecomposition(matriks);
        DoubleMatrix2D U = svd.getU();

        return U;
    }

    public DoubleMatrix2D getS() throws Exception {
        matriks = getMatriksTermDoc();
        SingularValueDecomposition svd = new SingularValueDecomposition(matriks);
        DoubleMatrix2D S = svd.getS();

        return S;
    }

    public DoubleMatrix2D getV() throws Exception {
        matriks = getMatriksTermDoc();
        SingularValueDecomposition svd = new SingularValueDecomposition(matriks);
        DoubleMatrix2D V = svd.getV();

        return V;
    }

    // Untuk mendapatkan low rank matriks U
    public DoubleMatrix2D getReducedU() throws Exception {
        k = getK();
        Algebra aljabar = new Algebra();
        DoubleMatrix2D U = getU();
        DoubleMatrix2D reducedU = aljabar.subMatrix(U, 0, U.rows() - 1, 0, k);

        return reducedU;
    }

    // Untuk mendapatkan low rank matriks V
    public DoubleMatrix2D getReducedV() throws Exception {
        k = getK();
        Algebra aljabar = new Algebra();
        DoubleMatrix2D V = getV();
        DoubleMatrix2D reducedV = aljabar.subMatrix(V, 0, V.rows() - 1, 0, k);

        return reducedV;
    }

    // Untuk mendapatkan low rank matriks S
    public DoubleMatrix2D getReducedS() throws Exception {
        k = getK();
        Algebra aljabar = new Algebra();
        DoubleMatrix2D S = getS();
        DoubleMatrix2D reducedS = aljabar.subMatrix(S, 0, k, 0, k);

        return reducedS;
    }

    @SuppressWarnings("unused")
	public double[][] bacaFileMatriks(String lokasiFile) throws Exception {
        BufferedReader input = new BufferedReader(new FileReader(lokasiFile));
        int count = 0; // Untuk menghitung baris matriks
        String line = null;
        while ((line = input.readLine()) != null) {
            count++;
        }
        input.close();
        //System.out.println(count + " baris.");

        double[][] ddArray = new double[count][];
        Scanner sc = new Scanner(new FileReader(lokasiFile));
        for (int baris = 0; baris < count; baris++) {
            if (sc.hasNextLine()) {
                String[] sArray = sc.nextLine().split(" ");
                double[] dArray = new double[sArray.length];
                for (int kolom = 0; kolom < sArray.length; kolom++) {
                    dArray[kolom] = Double.parseDouble(sArray[kolom]);
                }
                ddArray[baris] = dArray;
            }
        }
        sc.close();
        elemen = ddArray;
        return elemen;
    }

    public DoubleMatrix2D getMatriksTermDoc() throws Exception {
        elemen = bacaFileMatriks("src/thesis/files/term-document.matrix");
        matriks = new SparseDoubleMatrix2D(elemen);

        return matriks;
    }

    public DoubleMatrix2D getMatriksPseudoDoc() throws Exception {
        elemen = bacaFileMatriks("src/thesis/files/pseudo-document.matrix");
        matriks = new SparseDoubleMatrix2D(elemen);

        return matriks;
    }

    public int getK() throws Exception {
        matriks = getMatriksTermDoc();
        k = (int) Math.floor(Math.sqrt(matriks.columns()));

        return k;
    }
    
    public void cetakMatriks(DoubleMatrix2D matriks, String judul){

        for (int atas = 0; atas < judul.length(); atas++){
            System.out.print("-");
        }
        System.out.print("\n" + judul + "\n");
        for (int bawah = 0; bawah < judul.length(); bawah++){
            System.out.print("-");
        }
        System.out.println();

        for (int i = 0; i < matriks.rows(); i++) {
            for (int j = 0; j < matriks.columns(); j++) {
                System.out.printf("%10.5f", matriks.get(i, j));
            }
            System.out.println();
        }
        System.out.println();

    }
}
